1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

How to make an input box enable for only past dates and for the startdate if it falls in the current

Discussion in 'JavaScript' started by asifakhtar, Jun 12, 2023.

  1. #1
    How to make an input box enable for only past dates and for the startdate that if it falls in the current month in JavaScript.

    The input box should be disabled for the future dates and for the startdate if it falls in the current month and the current year.

    I have implemented the function but not sure the following logic will work for every scenario.

    const globalPendingStatusIDL3 = "76070";
    
    const check_IsExternalUser_And_PendingStatusL3 = (statusID = null, startDate = null) => {
    const now = new Date();
    const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() ));
    return !!statusID && !!startDate ? (statusID === "76070" && ((!(new Date(startDate)).getMonth() === new Date().getMonth() && new Date(startDate).getFullYear() === new Date().getFullYear()) || startDate.getTime() < today.getTime())) : false;
    };
    Code (markup):
    //Code where the input box is being created and disabled being set using a loop:
    strHTML += "<td width=\"100px\"><input class=\"form-control target-form\" data-recordid=\"" + recordid + "\" data-oldvalue=\"" + actualValue + "\" id=\"txtActualValue_" + recordid + "\" data-prevrecordid=\"" + (prevrecordid == "" ? "" : ("txtActualValue_" + prevrecordid)) + "\" value=\"" + actualValue + "\"" + (globalIsStaff ? "" : (check_IsExternalUser_And_PendingStatusL3(statusID,startDate) === true ? "disabled" : "")) + "/></td>";
    Code (markup):
    //Few scenarios and the desired result:
    check_IsExternalUser_And_PendingStatusL3("76070",new Date("2022-12-01")); //The input box should be enable
    check_IsExternalUser_And_PendingStatusL3("76070",new Date("2023-01-01")); //The input box should be enable
    check_IsExternalUser_And_PendingStatusL3("76070",new Date("2023-06-01")); //The input box should be disable
    check_IsExternalUser_And_PendingStatusL3("76070",new Date("2023-06-30")); //The input box should be disable
    check_IsExternalUser_And_PendingStatusL3("76070",new Date("2023-07-01")); //The input box should be disable
    check_IsExternalUser_And_PendingStatusL3("76070",new Date("2024-01-01")); //The input box should be disable
     
    Last edited by a moderator: Jun 12, 2023
    asifakhtar, Jun 12, 2023 IP
  2. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #2
    There are a lot of worries in that code. The markup in particular sets my teeth on edge being both broken/invalid, AND reeking of 1990's practices, and the use of innerHTML where if this is user generated content you just opened up a hole for XSS exploits!

    As to your logic, you're really overthinking it. Don't even get the day involved. If you want the current month / later disabled compare year with <=, compare month with <, done.

    I rarely agree with the "that function does too much" crowd, but that longass name and bloated logic; without any formatting to make it easy to understand? Not doing you any favors.

    Also your use of double bang would still return false on zero. A proper numeric check (parsefloat == original) would be more appropriate.

    
    const
    
    	disableStatusList = [ "76070" ],
    	
    	today = new Date(),
    	todayYear = today.getFullYear(),
    	todayMonth = today.getMonth(),
    	
    	isNumeric = (value) => parseFloat(value) == value,
    	
    	isExternalUser = (id) => isNumeric(id) && !disableStatusList.includes(id),
    	
    	isPendingStatus = (startDate) => (
    		startDate.getFullYear() <= todayYear
    	) && (
    		startDate.getFullMonth() < todayMonth
    	);
    
    Code (markup):
    Is how I'd approach the logic side. Also notice how you don't have to say "const" every uncle-huffing time? Yeah, that.

    Storing the current year/month in constants before the routine also speeds things up a bit so you're not calling those methods every joe-blasted call.

    As I said your markup is problematic. Even just simple things like:

    <td width=\"100px\">

    The width attribute doesn't accept PX, you want pixels in the width attribute you just say width="100". You don't say PX in width, that's what you say in CSS. The width attribute is NOT CSS.

    NOT that declaring a width has ANY business in your HTML any time after CSS came into existence.

    I'm also highly doubting this is actually tabular data.

    We also have something called template literals now (some folks call them backtick strings) that makes escaping double quotes no longer needed, and they work better for plugging in values too.

    It's also odd the crazy hoops you're jumping through to make an ID and pass it, when you don't have a NAME for it to actually submit by. Lemme guess, you're manually going to each one via getElementByID instead of just grabbing your entire form via formData? Rather than that I'd use array indexes in the server-side use of name="something[index]"

    
    	const
    		template_formActualValue(recordId, statusId, prevRecordId, actualValue) => {
    		
    			let dynamics = '';
    				
    			if (
    				isExternalUser(statusId) &&
    				isPendingStatus(statusId)
    			) dynamics += `
    						disabled`;
    						
    			if (prevRecordId) dynamics += `
    						data-prevrecordid="txtActualValue[{$prevRecordId}]"`;
    			return `
    				<td>
    					<input
    						class="formControl targetForm"
    						name="txtActualValue[${recordId}]"
    						data-recordid="${recordId}"
    						value="${$actualValue}"${dynamics}
    					>
    				</td>`;
    		}; // template_formActualValue
    
    Code (markup):
    NOT that I would slop together HTML as a string in 2023 unless this is server-side code for node.js

    If this is client side code, we go to the DOM.

    
    	const
    		template_formActualValue(tr, recordId, statusId, prevRecordId, value) => {
    			// table should be the your TR element's DOM node
    		
    			let input = Object.assign(
    				document.createElement("input"),
    				{
    					className : "formControl targetForm",
    					disabled : isExternalUser(statusId) && isPendingStatus(statusId),
    					name : `txtActualValue[${recordId}]`,
    					value
    				}
    			);
    				
    			input.dataList.recordId = recordId;
    				
    			if (prevRecordId) {
    				input.dataList.prevrecordid = `txtActualValue[${prevRecordId}]`;
    			}
    			
    			tr.appendChild(document.createElement("td")).appendChild(input);
    			
    		}; // template_formActualValue
    
    Code (markup):
    But that hinges greatly on where and how you are doing all this. Good rule of thumb though if you're creating HTML in your JavaScript, you're doing it all wrong unless you're 100% certain you're batching up a bunch of changes. And even then the security risks aren't worth it compared to attaching stuff via the DOM.

    cute trick there, if you state a variable like "value" in an object without a value declaration (the colon), the name of the variable is the property name, and the value of the variable is its value.

    { value }

    is functionally identical to:

    { "value" : value }

    Thus it's not a bad idea when possible to name your variables the same as the object properties they're being assigned to.

    As you can see either way, the new template literals are your friend. Well, unless you need this to support browsers made prior to 2016. And I've flipped 180 degrees on my opinion of such support. Screw those people!
     
    deathshadow, Jun 16, 2023 IP